#coding=utf-8

import os
import time
import string

import kernel
from func_ext import file_put_contents,list2str,ksort


class abstract_cron(object) :
    """""""""""""""""""""""""""""""""""""""""""""
     # 定时执行脚本基类
     # @class
     # @copyright Copyright (c) 2010, pe-dev. inc
     # @author alone <phperlon@gmail.com>
     # @license
    """""""""""""""""""""""""""""""""""""""""""""
    insertList = []     #批量插入的列表 (每项是一个tuple)
    insertFields = []   #要插入的字段
    noLock = False      #是否生成脚本锁文件 默认生成
    runLogTable = 'sdb_statistics_run_log'

    def __init__(self,fileIdent) :
        real_path = os.path.realpath(fileIdent)
        self.lockFile = real_path+'.lck'
        #检查是否有脚本锁文件存在
        self.checkLock()
        
        #获取配置信息
        self.setting = globals().get('setting',{})
        if not self.setting :
            from config import config
            self.setting = config().setting()

        dirName = os.path.dirname(real_path)
        baseName = os.path.basename(real_path)
        self.logFileIdent = os.path.splitext(baseName)[0]
        self.script_file = 'python/cron/'+baseName
        self.dateIdent = time.strftime('%Y%m%d')
        self.logDir = 'log/'+self.dateIdent
        self.objCore = kernel.core()
        self.db = self.objCore.database()
        self.mongo = self.objCore.mongo()
        self.start_time = int(time.time())

    def checkLock(self) :
        if os.path.isfile(self.lockFile) :
            print 'if you want to run this script,please delete the lock file'
            os._exit(0)
        elif not self.noLock :
            file_put_contents(self.lockFile,'this is lock file')
            os.chmod(self.lockFile,0777)

    def getTimeFilter(self,type,timestamp=[]) :
        keyFilter = {}
        keyFilter['date'] = timestamp and timestamp or (int(time.strftime('%Y%m%d'))-1)
        return keyFilter

    def preBoot(self) :
        filter = {}
        filter['script_file'] = self.script_file
        filter['day_date'] = self.dateIdent
        filter['disabled'] = 'false'
        sql = 'SELECT * FROM '+self.runLogTable+' WHERE '+self.db._filter(filter)
        row = self.db.selectRow(sql)
        if row :
            if os.path.isfile(self.lockFile) :
                os.remove(self.lockFile)
            print '该脚本今天已经运行过'
            os._exit(0)
            return True
        else :
            return False

    def sufBoot(self) :
        #删除脚本锁文件
        if os.path.isfile(self.lockFile) :
            os.remove(self.lockFile)
        #表中插入脚本运行信息
        end_time = int(time.time())
        log = {}
        log['start_time'] = self.start_time
        log['end_time'] = end_time
        log['script_file'] = self.script_file
        log['day_date'] = self.dateIdent
        #res = self.db.query('SELECT * FROM '+self.runLogTable+' WHERE 0=1')
        logSql = self.GetInsertSql(self.runLogTable,log)
        self.db.query(logSql)

    def GetInsertSql(self,table,data) :
        """""""""""""""""""""""""""""""""""""""
         # 获取插入的sql语句
         #
         # @author   alone <phperlon@gmail.com>
         # @param    
         # @return   void
         # @todo     
        """""""""""""""""""""""""""""""""""""""
        sql = 'INSERT INTO '+table
        keys = list2str(data.keys())
        sql += '(`'+string.join(keys,'`,`')+'`)'
        values = list2str(data.values())
        sql += 'VALUES("'+string.join(values,'","')+'")'
        return sql

    def _getBatchInsertSql(self) :
        sql = 'INSERT INTO '+self.insertTable
        keys = list2str(self.insertKeys())
        sql += '(`'+string.join(keys,'`,`')+'`)'
        repeat_format = string.strip('%s,'*len(keys),',')
        sql += 'VALUES('+repeat_format+')'
        return sql

    def getBatchInsertSql(self,fields=[]) :
        if not fields :
            fields = self.insertKeys()
        return self.db.getBatchInsertSql(self.insertTable,fields)

    def writeSql(self,sql,result,type) :
        """""""""""""""""""""""""""""""""""""""
         # 记录sql语句日志
         #
         # @author   alone <phperlon@gmail.com>
         # @param    
         # @return   void
         # @todo     
        """""""""""""""""""""""""""""""""""""""
        if not os.path.isdir(self.logDir) :
            os.makedirs(self.logDir)

        l_file = [self.logFileIdent,type,result]
        sql_file = self.logDir+'/'+string.join(l_file,'.')+'.log'

        pref = '['+time.strftime('%Y-%m-%d %H:%I:%S')+']    '
        content = pref+'('+sql+')'
        file_put_contents(sql_file,content+"\r\n",'FILE_APPEND')

    def filterItems(self,dic) :
        """""""""""""""""""""""""""""""""""""""
         # 过滤数据
         #
         # @author   alone <phperlon@gmail.com>
         # @param    dict dic 字典数据对象
         # @return   void
         # @todo     
        """""""""""""""""""""""""""""""""""""""
        insFields = set(self.insertKeys())
        inskeys = set(dic.keys())
        diffKey = inskeys-insFields
        if diffKey :
            for k in diffKey :
                dic.pop(k)

        defaultDiffKey = insFields - inskeys
        for v in defaultDiffKey :
            dic[v] = '0'
        
        tmp_dict = ksort(dic)
        #结果集的value为要插入的值 值为None的转换为0 注意要转换为元组
        vars = map(lambda x:x and x or 0,tmp_dict.get('value'))
        self.insertList.append(tuple(vars))

        if not self.insertFields :
            #结果集字典的key为要插入的字段
            self.insertFields = tmp_dict.get('key')

    def doBatchExec(self) :
        """""""""""""""""""""""""""""""""""""""
         # 执行批量操作
         #
         # @author   alone <phperlon@gmail.com>
         # @param    
         # @return   void
         # @todo     
        """""""""""""""""""""""""""""""""""""""
        if self.insertFields and self.insertList :
            batchInsSql = self.getBatchInsertSql(self.insertFields)
            self.db.batchExec(batchInsSql,self.insertList)

    def getNodeType(self) :
        objDB = self.objCore.database('shopex_certi')
        sql = 'SELECT `app_id` FROM svc_app_list WHERE status="true"'
        row = objDB.select(sql)
        typeList = []
        for v in row :
            typeList.append(str(v.get('app_id')))
        return filter(None,typeList)

    def figureRatio(self,data,sumKey,failKey,ratioKey=False) :
        """""""""""""""""""""""""""""""""""""""
         # 计算成功率
         #
         # @author   lazyfish <lazyfish.fan@gmail.com>
         # @param    dict data
         # @param    str allKey
         # @param    str failKey
         # @return   float
         # @todo     
        """""""""""""""""""""""""""""""""""""""
        sumNum = data.get(sumKey) and int(data.get(sumKey)) or 0
        failNum = data.get(failKey) and float(data.get(failKey)) or 0.0
        #过滤失败次数小于0
        if failNum < 0 :
            data[failKey] = 0
            failNum = 0
        if sumNum :
            ratio = round((1-failNum/sumNum),5)
        else :
            ratio = 1.0

        #过滤成功率小于0(上面已经对失败次数做过滤 这一步可以省去)
        final_ratio = (ratio > 1) and 1.0 or ratio

        if ratioKey and isinstance(ratioKey,str) :
            data[ratioKey] = final_ratio
        else :
            return final_ratio
